package com.sunseagear.wind.modules.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sunseagear.common.base.mvc.service.impl.TreeCommonServiceImpl;
import com.sunseagear.common.utils.StringUtils;
import com.sunseagear.wind.common.utils.UserUtils;
import com.sunseagear.wind.modules.sys.entity.Menu;
import com.sunseagear.wind.modules.sys.entity.vo.MenuVo;
import com.sunseagear.wind.modules.sys.mapper.MenuMapper;
import com.sunseagear.wind.modules.sys.service.IMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;

@Transactional
@Service("menuService")
@RequiredArgsConstructor
public class MenuServiceImpl extends TreeCommonServiceImpl<MenuMapper, Menu, Long> implements IMenuService {

    @Override
    public List<MenuVo> getCurrentUserMenuVos() {
        List<Menu> list = baseMapper.findMenuByUserId(UserUtils.getUser().getId());
        return buildMenu(getTreeTables(list, Comparator.comparing(Menu::getSort)));
    }

    @Override
    public List<Menu> getCurrentUserMenus() {
        List<Menu> list = baseMapper.findMenuByUserId(UserUtils.getUser().getId());
        return buildTree(getTreeTables(list, Comparator.comparing(Menu::getSort)));
    }

    @Override
    public List<Menu> findMenuAndPermissionByUserId(Long userId) {
        List<Menu> list = baseMapper.findMenuAndPermissionByUserId(userId);
        return buildTree(getTreeTables(list));
    }

    @Override
    public List<Menu> selectTreeList(Wrapper<Menu> wrapper) {
        List<Menu> list = super.list(wrapper);
        return this.buildTree(this.getTreeTables(list, Comparator.comparing(Menu::getSort)));
    }


    @Override
    public List<Menu> findMenuByUserId(Long userId) {
        return baseMapper.findMenuAndPermissionByUserId(userId);
    }

    @Override
    public List<Menu> findMenuByRoleId(Long roleId) {
        return baseMapper.findMenuByRoleId(roleId);
    }

    @Override
    public List<Menu> findPermissionByUserId(Long userId) {
        return baseMapper.findPermissionByUserId(userId);
    }

    @Override
    public List<Menu> findPermissionByRoleId(Long roleId) {
        return baseMapper.findPermissionByRoleId(roleId);
    }

    @Override
    public void changeSort(Long menuId, Integer sort) {
        Menu menu = getById(menuId);
        menu.setSort(sort);
        updateById(menu);
    }

    @Override
    public void generateButton(Long menuId,
                               String parentPermission,
                               String[] permissions,
                               String[] permissionTitles, Boolean additional) {
        if (!additional) {
            QueryWrapper<Menu> deleteEntityWrapper = new QueryWrapper<>();
            deleteEntityWrapper.eq("parent_id", menuId);
            deleteEntityWrapper.eq("type", 3);
            remove(deleteEntityWrapper);
        }
        QueryWrapper<Menu> countEntityWrapper = new QueryWrapper<>();
        countEntityWrapper.eq("t.parent_id", menuId);
        countEntityWrapper.eq("t.type", 3);

        int count = selectTreeList(countEntityWrapper).size();

        List<Menu> menuList = new ArrayList<>();
        for (int i = 0; i < permissions.length; i++) {
            Menu menu = new Menu();
            menu.setParentId(menuId);
            menu.setName(permissionTitles[i]);
            menu.setPermission(parentPermission + ":" + permissions[i]);
            menu.setSort(i + count);
            menu.setType("3");
            menu.setEnabled(Menu.YES);
            menuList.add(menu);
        }
        saveBatch(menuList);
    }


    public List<MenuVo> buildMenu(List<Menu> treeNodes) {
        List<MenuVo> treeNodeList = new ArrayList<>();
        HashMap<Long, MenuVo> treeEntityHashMap = new HashMap<>();
        treeNodes.forEach(item -> treeEntityHashMap.put(item.getId(), new MenuVo(item)));
        treeNodes.forEach(item -> {
            MenuVo menuTreeNode = treeEntityHashMap.get(item.getId());
            if (item.getParentId() != null
                    && !StringUtils.isEmpty(String.valueOf(item.getParentId()))
                    && treeEntityHashMap.containsKey(item.getParentId())) {
                MenuVo treeEntity = treeEntityHashMap.get(item.getParentId());
                treeEntity.getChildren().add(menuTreeNode);

            } else {
                treeNodeList.add(menuTreeNode);
            }
        });
        return treeNodeList;
    }


}
